package com.mindskip.xzs.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.ObjectUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

@Slf4j
public class RestLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    public RestLoginAuthenticationFilter() {
        // 以 "/api/user/login" 为登录接口
        super(new AntPathRequestMatcher("/api/user/login", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {

        UsernamePasswordAuthenticationToken authenticationToken;

        try (InputStream is = request.getInputStream()) {
            // 使用Jackson将JSON字符输入流转换为Java对象
            Map<String, Object> userInfo = new ObjectMapper().readValue(is, Map.class);
            String userName = (String) userInfo.get("userName");
            String password = (String) userInfo.get("password");
            Boolean rememberMe = (Boolean) userInfo.get("remember");
            if (!ObjectUtils.isEmpty(rememberMe)) {
                // rememberMe不为空 将"remember-me"属性存入到request域中
                request.setAttribute(TokenBasedRememberMeServices.DEFAULT_PARAMETER, rememberMe);
            }
            authenticationToken = new UsernamePasswordAuthenticationToken(userName, password);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            authenticationToken = new UsernamePasswordAuthenticationToken("", "");
        }

        setDetails(request, authenticationToken);
        return this.getAuthenticationManager().authenticate(authenticationToken);
    }

    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }

}
